package com.zhouixi.entity;

import com.zhouixi.handler.WebSocketHandler;
import jakarta.annotation.Resource;
import lombok.Data;
import org.springframework.stereotype.Component;

import java.util.concurrent.*;

@Component
public class LocalMessageQueue {
    // 每个用户对应一个阻塞队列
    private static final ConcurrentMap<Long, BlockingQueue<Message>> queues = new ConcurrentHashMap<>();
    // 线程池处理消息投递
    private static final ExecutorService executor = Executors.newCachedThreadPool();

    @Resource
    private WebSocketHandler webSocketHandler;

    static {
        // 启动定时清理线程
        ScheduledExecutorService cleaner = Executors.newSingleThreadScheduledExecutor();
        cleaner.scheduleAtFixedRate(() -> {
            queues.entrySet().removeIf(entry -> entry.getValue().isEmpty());
        }, 1, 1, TimeUnit.HOURS);
    }

    public void addMessage(Long userId, String content) {
        BlockingQueue<Message> queue = queues.computeIfAbsent(userId, k ->
                new LinkedBlockingQueue<>(1000)); // 每个用户最多缓存1000条消息

        try {
            queue.put(new Message(userId, content));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        // 立即触发消费
        executor.submit(() -> processQueue(userId));
    }

    public void processQueue(Long userId) {
        BlockingQueue<Message> queue = queues.get(userId);
        if (queue == null) {
            return;
        }

        while (!queue.isEmpty()) {
            Message msg = queue.poll();
            if (msg != null) {
                // 调用WebSocket发送
                boolean flag = webSocketHandler.sendToUser(msg.getReceiverId(), msg.getContent());
                if(!flag) {
                    addMessage(msg.getReceiverId(), msg.getContent()); // 发送失败，重新加入队列
                }
            }
        }
    }

    @Data
    public static class Message {
        private Long receiverId;

        private String content;

        public Message(Long receiverId, String content) {
            this.receiverId = receiverId;
            this.content = content;
        }
        // Getters
    }
}